package com.exd.kafka.service;

import com.alibaba.fastjson2.JSONObject;
import com.exceeddata.ac.format.convert.CsvToVswConverter;
import com.exceeddata.sdk.vdata.data.VDataFrame;
import com.exceeddata.sdk.vdata.data.VDataReader;
import com.exceeddata.sdk.vdata.data.VDataRow;
import java.io.*;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

public class MockVdataVsw2 {
    public static List<String> mockCsvRow(String sinals, long time, long limit, int cycle) {
        DateFormat timeFormat = getZonedDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //信号时间格式化
        long startTime = time * 1000;

        String formatTime = "";
        StringBuilder sb;
        List<String> dataList = new ArrayList<>();
        dataList.add(sinals);
        for (long i = 0; i < limit; i++) {
            sb = new StringBuilder("");
            formatTime = timeFormat.format(startTime);
            sb.append(formatTime).append(",56,1,1,0,32958,1,").append(i+1);
            dataList.add(sb.toString());
            startTime += cycle;
        }
        return dataList;
    }

    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }

    public static void writeFile(File writeFile, List<String> data) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter(writeFile));
        for (int i = 0; i < data.size(); i++) {
            bw.write(data.get(i));
            bw.newLine();
        }
        bw.close();
    }

    public static void csvToVswFile(String csvFilePath, String vswFilePath) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(vswFilePath);
        CsvToVswConverter csvToVswConverter = new CsvToVswConverter();
        csvToVswConverter.setInputFile(csvFilePath);
        csvToVswConverter.setTimeColumnName("msg_time");
        csvToVswConverter.setOutputStream(fileOutputStream);
        csvToVswConverter.convert();
    }

    public static Long getLocalDateTimeSecond(LocalDateTime localDateTime){
        return localDateTime.toEpochSecond(ZoneOffset.of("+8"));
    }

    public static String headerToString(final List<String> cols, final StringBuilder sb) {
        sb.setLength(0);
        sb.append("msg_time");
        for (final String n : cols) {
            sb.append(',').append(n);
        }
        sb.append('\n');
        return sb.toString();
    }

    public static String rowToString(
            VDataRow row,
            StringBuilder sb,
            DateFormat timeFormat,
            DecimalFormat fmt) {
        sb.setLength(0);
        sb.append(timeFormat.format(row.getTime().toEpochMilli()));
        for (Object d: row.getValues()) {
            sb.append(',');
            if (d != null) {
                sb.append(fmt.format(d));
            }
        }
        sb.append('\n');
        return sb.toString();
    }

    public static void writerToFile(String vswData, String filename) throws Exception {
        DateFormat dateFormat = getZonedDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //信号时间格式化
        DecimalFormat decimalFormat = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); //信号时间格式化
        decimalFormat.setMaximumFractionDigits(10);

        byte[] vswByte = Base64.getDecoder().decode(vswData);

        FileWriter fileWriter = new FileWriter(filename);
        StringBuilder stringBuilder = new StringBuilder(4096);

        VDataRow row = null;
        VDataReader reader = new VDataReader(vswByte, null);
        VDataFrame df = reader.df();

        Iterator<VDataRow> iter = df.iterator(Integer.valueOf(1000));

        //header
        if (iter.hasNext()) {
            fileWriter.write(headerToString(df.cols(), stringBuilder));
        }

        //rows
        while (iter.hasNext()) {
            row = iter.next();
            fileWriter.write(rowToString(row, stringBuilder, dateFormat, decimalFormat));
        }

        fileWriter.flush();
        fileWriter.close();
    }

    public static byte[] readFromByteFile(String file) throws IOException {
        File filename = new File(file);
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename));
        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
        byte[] temp = new byte[1024];
        int size = 0;
        while((size = in.read(temp)) != -1){
            out.write(temp, 0, size);
        }
        in.close();
        return out.toByteArray();
    }

    public static DateFormat getZonedDateFormat(String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        TimeZone TIMEZONE = TimeZone.getTimeZone("Asia/Shanghai");
        dateFormat.setTimeZone(TIMEZONE);
        return dateFormat;
    }

    public static String mockVswString(String pathString, Long milliSecond, int second, int cycle, String header) throws Exception {
        String path = pathString + milliSecond +"/";
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }

        String csvFile = path + "alarm.csv";
        String vswFile = path + "alarm.vsw";

        long limit = second * (1000/cycle);

        // mock csv
        List<String> data = mockCsvRow(header, milliSecond, limit, cycle);
        writeFile(new File(csvFile), data);

        // csv -> vsw
        csvToVswFile(csvFile, vswFile);

        // vsw -> string
        byte[] vswBytes = readFromByteFile(vswFile);
        return Base64.getEncoder().encodeToString(vswBytes);
    }

    public static void main(String[] args) throws Exception {
        int second = 180;
        int cycle = 10;
        Long milliSecond = getLocalDateTimeSecond(LocalDateTime.now()) - second;
        String path = "/Users/zhaowei/Desktop/test/vsw/";
        String pathString =  path + milliSecond +"/";

        // 生成vsw
        String vswData = mockVswString(path, milliSecond, second, cycle,"msg_time,Viu_mr.1487.OIB_VCU_Test2.HvStateNr,Viu_r.484.VIU_OIB_EBS_0x35_VIU_R.ebs_SOC_STATE_60_VIUR,Viu_r.481.VIU_OIB_EBS_0x34_VIU_R.ebs_T_BATT_60_VIUR,Viu_r.481.VIU_OIB_EBS_0x34_VIU_R.ebs_I_RANGE_60_VIUR,Viu_r.481.VIU_OIB_EBS_0x34_VIU_R.ebs_I_BATT_60_VIUR,Viu_r.481.VIU_OIB_EBS_0x34_VIU_R.ebs_U_BATT_60_VIUR,Viu_r.484.VIU_OIB_EBS_0x35_VIU_R.ebs_SOC_60_VIUR");

        // 解析vsw
        String csvFile = pathString + "parse.csv";
        writerToFile(vswData, csvFile);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("collectionTime", milliSecond * 1000);
        jsonObject.put("data", vswData);
        jsonObject.put("vin", "LDP91H964RE000135");

        System.out.println(jsonObject.toJSONString());
    }

}
